﻿using GrainManage.Core.Access.Interfaces;
using GrainManage.Core.Provider.Interfaces;
using System.Data;
using System.Data.Common;

namespace GrainManage.Core.Access
{
    public class ProcAccess : IAccess
    {
        #region Private Method and Construct
        private IProvider provider;
        private IParameterBuilder parameterBuilder;

        public ProcAccess(IProvider provider, IParameterBuilder parameterBuilder)
        {
            this.provider = provider;
            this.parameterBuilder = parameterBuilder;
        }

        /// <summary>
        /// 为命令添加参数
        /// </summary>
        /// <param name="cmd">命令</param>
        /// <param name="parameterValues">参数的值的集合,且值一定要按照参数顺序写</param>
        /// <returns>参数匹配则返回true,否则返回false</returns>
        private void AddParameters(DbCommand cmd, object[] parameterValues)
        {
            parameterBuilder.AddParameters(cmd, parameterValues);
        }

        #endregion

        #region Public Method

        /// <summary>
        /// 获取结果集
        /// </summary>
        /// <param name="procName">存储过程名</param>
        /// <param name="paraValues"></param>
        /// <returns></returns>
        public DataSet ExecuteQuery(string procName, params object[] paraValues)
        {
            var dtResult = new DataSet(procName);
            var adapter = provider.GetAdapter(procName);
            AddParameters(adapter.SelectCommand, paraValues);
            adapter.Fill(dtResult);
            return dtResult;
        }

        /// <summary>
        /// 获取单行单列的值
        /// </summary>
        /// <param name="procName"></param>
        /// <param name="paraValues"></param>
        /// <returns></returns>
        public object ExecuteScalar(string procName, params object[] paraValues)
        {
            using (var con = provider.Connection)
            {
                var cmd = provider.GetCommand(procName, con);
                AddParameters(cmd, paraValues);
                con.Open();
                var paras = cmd.ExecuteScalar();
                return paras;
            }
        }

        /// <summary>
        /// 执行更新、删除、插入等命令
        /// </summary>
        /// <param name="procName"></param>
        /// <param name="paraValues"></param>
        /// <returns></returns>
        public int Execute(string procName, params object[] paraValues)
        {
            using (var con = provider.Connection)
            {
                var cmd = provider.GetCommand(procName, con);
                AddParameters(cmd, paraValues);
                con.Open();
                var count = cmd.ExecuteNonQuery();
                return count;
            }
        }

        /// <summary>
        /// 获取行读取器
        /// </summary>
        /// <param name="procName"></param>
        /// <param name="paraValues"></param>
        /// <returns></returns>
        public DbDataReader ExecuteReader(string procName, params object[] paraValues)
        {
            using (var cmd = provider.GetCommand(procName, provider.Connection))
            {
                AddParameters(cmd, paraValues);
                cmd.Connection.Open();
                return cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
        }

        #endregion
    }
}
